home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
titlbar.exe
/
READ.ME
< prev
next >
Wrap
Text File
|
1992-10-03
|
7KB
|
142 lines
An application I developed had the specification that the screen (ie
TProgram) had to have a title bar at the top at all times. This was simple
enough (description below), but I found that with the title above the menu
bar, the mouse would enter the title region when moved to the top of the
screen. This was quite annoying; anyone used to a standard TV-type interface
(NOT Windows) is used to whipping the mouse to the top, 'diagonally' moving
to a menu item, and clicking. With the mouse able to enter the title region,
the user can't do this: you have to move the mouse down one row for it to
be on the menu bar. I solved this problem, and present my solution here.
The solution involves modifying the original TV source code (in
particular, TMOUSE.CPP and SYSTEM.H). For those of you who do not have the
TV source code, I've included NEWMOUSE.OBJ (I can't include the TMOUSE.CPP
modified code, since it is copyrighted material of Borland's); just include
NEWMOUSE.OBJ in your project when building a TV application and (with the
mods to SYSTEM.H) you will also be able to use this feature.
Discussion.
Using a title bar in a TV application can be very easy - or a bit
difficult - depending on your needs. The easy part is just having a title
bar at the top of the screen; all you need to do is derive a proper TView
class (I use TStaticText), insert it into TProgram (at the top), adjust
the menu bar and desktop, and you're done. Here's an example of a title bar
class that is 1 row high and uses black-on-green and centered text:
class TTitleBar : public TStaticText
{
public:
TTitleBar( const TRect& bounds, const char *aText );
virtual TPalette& getPalette() const;
};
The full declaration for this class can be found in TTITLBAR.H, and the
definition in TTITLBAR.CPP. The concept here is that the title bar is just
a TStaticText-type object, with getPalette() overridden to use the
appropriate entry in TProgram's palette (since a standard TStaticText is
designed to be inserted into a TDialog, its palette is probably not what
you want your title bar to be). Since we want the title centered, we make
sure that when TTitleBar's ctor is called, the aText argument has a leading
'\003' character - this tells TStaticText to center the text.
In a normal application, the menubar has its origin member set to
(0,0), and the desktop has its set to (0,1). This is reflected in the
standard start of a normal initMenuBar(...) method:
TMenuBar *TMyApp::initMenuBar( TRect r )
{
r.b.y = r.a.y+1; // r.a = (0,0)
return new TMenuBar(r, ...); // r = (0,0,80,1)
}
and the normal initDeskTop(...) method:
TDeskTop *TMyApp::initDeskTop( TRect r )
{
r.a.y++;
r.b.y--;
return new TDeskTop(r); // r = (0,1,80,24)
}
But our new title bar is going to occupy row 0, so these two methods have
to be changed to accomodate it: this can be seen in TEST.CPP. We don't have
to change initStatusLine(...) since it still occupies the bottom row of the
screen.
This works fine, but the mouse can go into the title bar region; so now
comes the 'bit difficult' part. If you examine SYSTEM.H, you'll see that
the class TMouse has only one range-setting method (setRange(...)) and that
it only takes 2 arguments: the new right and bottom ranges - the top and
left are *assumed* to start at (0,0). So the first thing we have to do is
modify TMouse (and THWMouse) to accept *at least* the top row as an argument,
along with the right and bottom arguments. As a general method however,
something like:
void THWMouse::setRange( ushort top, ushort rx, ushort ry );
is a bit restrictive - as long as we're making a method that will restrict
the mouse range, we should make it comprehensive - allow it to have a full
rectangular argument. This has the benefit of: if you want to restrict the
mouse movement to a window on the screen, you can do so. But before I show
the code changes that will implement this, we need to be cautious; there are
a number of times when TV calls TMouse::setRange(rx,ry) (a bug fix for TV1.0
<incorporated into TV1.03> calls setRange when TProgram::setScreenMode is
called). An example of this is shown in TEST.CPP - the single menubar item
File has a submenu item Change screen mode - it toggles from 25 to 43/50
line mode. When the screen mode is changed,
TMouse::setRange( TScreen::screenWidth-1, TScreen::screenHeight-1 );
is called - and our 'dead' mouse range in the title bar region goes away!
We can fix this by also changing TMouse::setRange(ushort,ushort) so that,
instead of using a default of (0,0) for the top-left coordinate, uses
(mouseOffset.x, mouseOffset.y), where TPoint mouseOffset is (0,0) by default,
but is changed when we make the setRange(const TRect&) call. Here's how all
of this is done:
[File: SYSTEM.H]
class THWMouse:
*add the following protected method:
static void setRange( const TRect& bounds );
class TMouse:
*add the following public method:
static void setRange( const TRect& bounds );
immediately following class TMouse:
* add the following inline definition:
inline void TMouse::setRange( const TRect& bounds )
{
THWMouse::setRange(bounds);
}
[File: TMOUSE.CPP]
near the top of the file:
*add the following static variable:
static TPoint mouseOffset = { 0, 0 };
method THWMouse::setRange(ushort,ushort):
*comment out the listed code and in its place use:
{
setRange( TRect(mouseOffset.x,mouseOffset.y,rx,ry) );
}
just after THWMouse::setRange(ushort,ushort):
*add the following method:
void THWMouse::setRange( const TRect& bounds )
{
if( buttonCount != 0 )
{
TRect r = bounds;
r.a.x <<= 3;
r.a.y <<= 3;
r.b.x <<= 3;
r.b.y <<= 3;
_DX = r.b.x;
_CX = r.a.x;
_AX = 7;
geninterrupt( 0x33 );
_DX = r.b.y;
_CX = r.a.y;
_AX = 8;
geninterrupt( 0x33 );
mouseOffset = bounds.a;
}
}
Note: if you do not have the TV source code, the file NEWMOUSE.OBJ that was
included with this file contains the above changes in compiled form.
The enclosed files TTitlbar.h and TTitlebar.cpp include the code for a
title bar class. The enclosed file Test.cpp shows using this class to
implement a title bar in an application, as well as using the modified
TMouse class to keep the mouse cursor out of the title bar region. For
demonstration purposes a menu entry allows you to swap from 25 to 43/50 line
mode to show that the mouse restricted movement works as planned.
If, for some reason, you want to be able to read the mouseOffset value,
add a new method to TMouse and have it return mouseOffset. I did not
implement this because I could not see a use for this information. If you
make other changes to TMouse and THWMouse, DO NOT (!) modify mouseOffset -
use setRange() to do so.
Pat Reilly 700274,161